/**
 * MicrophoneSDK单元测试
 */

import { MicrophoneSDK } from '../../src/MicrophoneSDK';

// 导入清理函数
const { clearMocks, restorePerformanceNow } = require('../setup');

// 模拟事件触发
const triggerEvent = (eventName) => {
  const event = new Event(eventName);
  document.dispatchEvent(event);
};

describe('MicrophoneSDK测试', () => {
  let sdk;
  
  beforeEach(() => {
    // 创建SDK实例
    sdk = new MicrophoneSDK();
  });
  
  afterEach(() => {
    // 清理资源
    if (sdk) {
      sdk.dispose();
      sdk = null;
    }
    // 清理模拟
    clearMocks();
  });
  
  afterAll(() => {
    // 恢复原始函数
    restorePerformanceNow();
  });
  
  test('SDK实例化', () => {
    expect(sdk).toBeInstanceOf(MicrophoneSDK);
  });
  
  test('SDK初始化', async () => {
    const initResult = await sdk.initialize();
    expect(initResult).toBe(true);
  });
  
  test('解锁音频上下文', () => {
    expect(() => sdk._unlockAudioContext()).not.toThrow();
    
    // 模拟用户交互事件
    triggerEvent('click');
    triggerEvent('touchstart');
    triggerEvent('keydown');
  });
  
  test('开始和停止监听', async () => {
    await sdk.initialize();
    
    const startResult = await sdk.startListening();
    expect(startResult).toBe(true);
    
    const stopResult = await sdk.stopListening();
    expect(stopResult).toBe(true);
  });
  
  test('获取麦克风状态', async () => {
    await sdk.initialize();
    
    // 初始状态应该是未监听
    expect(sdk.getMicrophoneStatus()).toBe('inactive');
    
    // 开始监听后状态应该变为活动
    await sdk.startListening();
    expect(sdk.getMicrophoneStatus()).toBe('active');
    
    // 停止监听后状态应该变回未监听
    await sdk.stopListening();
    expect(sdk.getMicrophoneStatus()).toBe('inactive');
  });
  
  test('选择麦克风', async () => {
    await sdk.initialize();
    
    // 模拟设备列表
    const devices = [
      { deviceId: 'default', kind: 'audioinput', label: 'Default' },
      { deviceId: 'device1', kind: 'audioinput', label: 'Microphone 1' }
    ];
    
    // 选择麦克风
    const result = await sdk.selectMicrophone('device1');
    expect(result).toBe(true);
  });
  
  test('刷新麦克风列表', async () => {
    await sdk.initialize();
    
    const devices = await sdk.refreshMicrophoneList();
    expect(Array.isArray(devices)).toBe(true);
    expect(devices.length).toBeGreaterThan(0);
  });
  
  test('设置增益', () => {
    const testGain = 0.7;
    sdk.setGain(testGain);
    
    // 由于我们无法直接访问内部的增益值，这里只测试方法不抛出错误
    expect(() => sdk.setGain(testGain)).not.toThrow();
  });
  
  test('加载自定义UI', async () => {
    await sdk.initialize();
    
    const container = document.createElement('div');
    document.body.appendChild(container);
    
    const result = await sdk.loadCustomUI(container);
    expect(result).toBe(true);
    
    document.body.removeChild(container);
  });
  
  test('获取麦克风流', async () => {
    await sdk.initialize();
    await sdk.startListening();
    
    const stream = sdk.getMicrophoneStream();
    expect(stream).not.toBeNull();
  });
  
  test('注册音频数据回调', async () => {
    await sdk.initialize();
    
    const mockCallback = jest.fn();
    sdk.registerAudioDataCallback(mockCallback);
    
    // 开始监听以触发音频处理
    await sdk.startListening();
    
    // 由于我们无法直接触发音频处理事件，这里只测试注册不抛出错误
    expect(() => sdk.registerAudioDataCallback(mockCallback)).not.toThrow();
  });
  
  test('设置音频处理配置', async () => {
    await sdk.initialize();
    
    const testConfig = {
      enableProcessing: true,
      sampleRate: 16000,
      bufferSize: 2048,
      channelCount: 1
    };
    
    sdk.setAudioProcessingConfig(testConfig);
    
    // 由于我们无法直接访问内部的配置，这里只测试方法不抛出错误
    expect(() => sdk.setAudioProcessingConfig(testConfig)).not.toThrow();
  });
  
  test('获取音频处理配置', async () => {
    await sdk.initialize();
    
    const config = sdk.getAudioProcessingConfig();
    expect(config).toEqual(expect.objectContaining({
      enableProcessing: expect.any(Boolean),
      sampleRate: expect.any(Number),
      bufferSize: expect.any(Number),
      channelCount: expect.any(Number)
    }));
  });
  
  test('处理初始化失败', async () => {
    // 模拟navigator.mediaDevices不可用的情况
    const originalMediaDevices = navigator.mediaDevices;
    navigator.mediaDevices = null;
    
    const newSdk = new MicrophoneSDK();
    const initResult = await newSdk.initialize();
    
    expect(initResult).toBe(false);
    
    // 恢复原始值
    navigator.mediaDevices = originalMediaDevices;
    newSdk.dispose();
  });
  
  test('处理开始监听失败', async () => {
    await sdk.initialize();
    
    // 模拟getUserMedia失败
    const originalGetUserMedia = navigator.mediaDevices.getUserMedia;
    navigator.mediaDevices.getUserMedia = jest.fn().mockRejectedValue(new Error('Permission denied'));
    
    const startResult = await sdk.startListening();
    expect(startResult).toBe(false);
    
    // 恢复原始值
    navigator.mediaDevices.getUserMedia = originalGetUserMedia;
  });
  
  test('处理选择麦克风失败', async () => {
    await sdk.initialize();
    
    // 模拟无效的设备ID
    const result = await sdk.selectMicrophone('invalid-device-id');
    expect(result).toBe(false);
  });
  
  test('资源释放', () => {
    expect(() => sdk.dispose()).not.toThrow();
  });
}); 